package com.drawquest.network;

import com.drawquest.exception.BadResponseException;
import com.gooddies.wiring.annotations.PostWiring;
import com.gooddies.wiring.annotations.WiringComponent;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.X509TrustManager;
import org.apache.commons.io.IOUtils;

/**
 * @author sad
 */
@WiringComponent(singleton = true, lazy = true)
public class Downloader {

    public enum HttpMethod {

        GET, POST
    };

    @PostWiring
    private void trustEveryone() {
        try {
            HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });
            SSLContext context = SSLContext.getInstance("TLS");
            context.init(null, new X509TrustManager[]{new X509TrustManager() {
                    @Override
                    public void checkClientTrusted(X509Certificate[] chain,
                            String authType) throws CertificateException {
                    }

                    @Override
                    public void checkServerTrusted(X509Certificate[] chain,
                            String authType) throws CertificateException {
                    }

                    @Override
                    public X509Certificate[] getAcceptedIssuers() {
                        return new X509Certificate[0];
                    }
                }}, new SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(
                    context.getSocketFactory());
        } catch (NoSuchAlgorithmException | KeyManagementException e) { // should never happen 
            e.printStackTrace();
        }
    }

    public String download(String url, HttpMethod method) {
        try {
            URL urlObject = new URL(url);
            HttpURLConnection connection = (HttpURLConnection) urlObject.openConnection();
            connection.setRequestMethod(method.toString());
            connection.connect();
            int responseCode = connection.getResponseCode();
            if (responseCode != 200) {
                throw new BadResponseException(IOUtils.toString(connection.getErrorStream(), "UTF-8"), responseCode);
            }

            return IOUtils.toString(connection.getInputStream(), "UTF-8");
        } catch (MalformedURLException ex) {
            throw new RuntimeException(ex);
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }
}
